package com.yutong.fmp.legal.utils.retry;

import java.util.Map;
import java.util.function.Supplier;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.yutong.fmp.common.core.result.Result;
import com.yutong.fmp.common.core.utils.UUIDUtil;
import com.yutong.fmp.legal.send.entity.LegalSendRecord;
import com.yutong.fmp.legal.send.service.LegalSendRecordService;
import com.yutong.fmp.legal.utils.MapUtils;
import com.yutong.fmp.legal.utils.ResultUtils;

import reactor.core.Reactor;
import reactor.event.Event;

/**
 * 重试改良版
 * 
 * @author bkszkjb07
 *
 */
@Component
@SuppressWarnings("all")
public class RetryHandle<T> {
	
	@Autowired
	private LegalSendRecordService legalSendRecordService;

	@Autowired
	private Reactor reactor;
	
	
	public interface RetryFlow<T> {

		public Supplier<Result<T>> exeRquest();

		public default String generateSendId(){return UUIDUtil.getUUID();};
		
		public LegalSendRecord insertRequestRecord(String resultBody);

		public Map<String,Object> enableRetry(Supplier<Result<T>> exeRquest ,MapUtils param);
		
		public default void success(Result<T> result) { };
	}

	public T handle(RetryFlow retryFlow) {
		boolean isException=false;
		String exceptionMessage="";
		Supplier<Result<T>> exeRquest = Result::error ;
		try {
			exeRquest= retryFlow.exeRquest();
		} catch (Exception e) {
			isException=true;
			exceptionMessage=ExceptionUtils.getFullStackTrace(e);
		}
		// 执行请求方法
		Result<T> result = exeRquest.get();

		boolean isSuccess=true;
		String status="1";
		// 判断是否实行成功
		if (!ResultUtils.isOk(result)) {
			isSuccess=false;
			status="0";
		}
		
		String resultBody=isException ? exceptionMessage:"";
		if(result.toString().length()>430) {
			resultBody=result.toString().substring(0, 370);
		}else
			resultBody=result.toString();
		
		 LegalSendRecord insertRequestRecord = retryFlow.insertRequestRecord(resultBody);
		 insertRequestRecord.setStatus(status);
		 String sendId = retryFlow.generateSendId();
		 insertRequestRecord.setFdId(sendId);
		 int insertSendRecord = legalSendRecordService.insertSendRecord(insertRequestRecord);
		 
		 if(!isSuccess) {
			 MapUtils map = MapUtils.bulid().put("sendId", sendId);
			 Map<String, Object> enableRetry = retryFlow.enableRetry(exeRquest,map);
			 reactor.notify("RetryHandleListener", Event.wrap(map));
		 }else
			 retryFlow.success(result);
		 
		 return result.getData();
	}

}
